package com.feng.modules.core.util;

import java.security.MessageDigest;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.ibatis.builder.xml.dynamic.ForEachSqlNode;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.property.PropertyTokenizer;
import org.apache.ibatis.session.SqlSessionFactory;

import com.feng.modules.page.MyBatisSql;

public class BaseUtils {
	
	private static String uuId = new String();
	
	//十六进制下数字到字符的映射数组
    private final static String[] hexDigits = {"0", "1", "2", "3", "4",
        "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

	/** 获取一个新的ID **/
	public final static String newUUID() {
		uuId = UUID.randomUUID().toString().toUpperCase().replaceAll("-", "");
		return uuId;

	}

	/** 获取之前产生的ID **/
	public final static String UUID() {
		if (uuId.isEmpty()) {
			uuId = UUID.randomUUID().toString().toUpperCase()
					.replaceAll("-", "");
		}
		return uuId;

	}

	
	

    /** * 把inputString加密     */
    public static String getChangePassword(String inputString){
        return encodeByMD5(inputString);
    }
    
      /**
       * 验证输入的密码是否正确
     * @param password    加密后的密码
     * @param inputString    输入的字符串
     * @return    验证结果，TRUE:正确 FALSE:错误
     */
    public static boolean validatePassword(String password, String inputString){
        if(password.equals(encodeByMD5(inputString))){
            return true;
        } else{
            return false;
        }
    }
    /**  对字符串进行MD5加密     */
    private static String encodeByMD5(String originString){
        if (originString != null){
            try{
                //创建具有指定算法名称的信息摘要
                MessageDigest md = MessageDigest.getInstance("MD5");
                //使用指定的字节数组对摘要进行最后更新，然后完成摘要计算
                byte[] results = md.digest(originString.getBytes());
                //将得到的字节数组变成字符串返回
                String resultString = byteArrayToHexString(results);
                return resultString.toUpperCase();
            } catch(Exception ex){
                ex.printStackTrace();
            }
        }
        return null;
    }
    
    /** 
     * 转换字节数组为十六进制字符串
     * @param     字节数组
     * @return    十六进制字符串
     */
    private static String byteArrayToHexString(byte[] b){
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++){
            resultSb.append(byteToHexString(b[i]));
        }
        return resultSb.toString();
    }
    
    /** 将一个字节转化成十六进制形式的字符串     */
    private static String byteToHexString(byte b){
        int n = b;
        if (n < 0)
            n = 256 + n;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }
    
    public static void main(String[] args) {
		// System.out.println(BaseTools.newUUID());
//		System.out.println(BaseTools.UUID());
		// System.out.println(BaseTools.newUUID());
		System.out.println(getChangePassword("123"));

	}
    
    /**
     * 运行期获取MyBatis执行的SQL及参数
     * 
     * @param id
     *            Mapper xml 文件里的select Id
     * @param parameterMap
     *            参数
     * @param sqlSessionFactory
     * @return
     */
    public static MyBatisSql getMyBatisSql(String id, Map<String, Object> parameterMap, SqlSessionFactory sqlSessionFactory) {
	MyBatisSql ibatisSql = new MyBatisSql();
	MappedStatement ms = sqlSessionFactory.getConfiguration().getMappedStatement(id);
	BoundSql boundSql = ms.getBoundSql(parameterMap);
	ibatisSql.setSql(boundSql.getSql());
	List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
	if (parameterMappings != null) {
	    Object[] parameterArray = new Object[parameterMappings.size()];
	    ParameterMapping parameterMapping = null;
	    Object value = null;
	    Object parameterObject = null;
	    MetaObject metaObject = null;
	    PropertyTokenizer prop = null;
	    String propertyName = null;
	    String[] names = null;
	    for (int i = 0; i < parameterMappings.size(); i++) {
		parameterMapping = parameterMappings.get(i);
		if (parameterMapping.getMode() != ParameterMode.OUT) {
		    propertyName = parameterMapping.getProperty();
		    names = propertyName.split("\\.");
		    if (propertyName.indexOf(".") != -1 && names.length == 2) {
			parameterObject = parameterMap.get(names[0]);
			propertyName = names[1];
		    } else if (propertyName.indexOf(".") != -1 && names.length == 3) {
			parameterObject = parameterMap.get(names[0]); // map
			if (parameterObject instanceof Map) {
			    parameterObject = ((Map) parameterObject).get(names[1]);
			}
			propertyName = names[2];
		    } else {
			parameterObject = parameterMap.get(propertyName);
		    }
		    metaObject = parameterMap == null ? null : MetaObject.forObject(parameterObject);
		    prop = new PropertyTokenizer(propertyName);
		    if (parameterObject == null) {
			value = null;
		    } else if (ms.getConfiguration().getTypeHandlerRegistry().hasTypeHandler(parameterObject.getClass())) {
			value = parameterObject;
		    } else if (boundSql.hasAdditionalParameter(propertyName)) {
			value = boundSql.getAdditionalParameter(propertyName);
		    } else if (propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX) && boundSql.hasAdditionalParameter(prop.getName())) {
			value = boundSql.getAdditionalParameter(prop.getName());
			if (value != null) {
			    value = MetaObject.forObject(value).getValue(propertyName.substring(prop.getName().length()));
			}
		    } else {
			value = metaObject == null ? null : metaObject.getValue(propertyName);
		    }
		    parameterArray[i] = value;
		}
	    }
	    ibatisSql.setParameters(parameterArray);
	}
	return ibatisSql;
    }


}